﻿using Reticulum.User;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Reticulum.Communication
{
    public partial class MasterForm : Form
    {
        List<Socket> ClienProSocketlist = new List<Socket>();
        public MasterForm()
        {
            InitializeComponent();
        }

        private void butsendMsg_Click(object sender, EventArgs e)
        {
            foreach (var proxSocket in ClienProSocketlist)
            {
                if (proxSocket.Connected)
                {
                    byte[] data = Encoding.Default.GetBytes(texMsg.Text);
                    proxSocket.Send(data, 0, data.Length, SocketFlags.None);
                }
            }
        }

        public void AccoptClientConnect(object socket)
        {
            var serverSocket = socket as Socket;

            this.AppendTextTolog("服务器开始接收客户端的链接");

            while (true)
            {
                try
                {
                    var proxSocket = serverSocket.Accept();
                    this.AppendTextTolog(string.Format("客户端：{0}链接上了", proxSocket.RemoteEndPoint.ToString()));
                    ClienProSocketlist.Add(proxSocket);

                    //不停的接受当前链接的客户端发送来的消息
                    //proxSocket.Receive();
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveDate), proxSocket);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

        }
        //接受客户端的消息
        public void ReceiveDate(object socket)
        {
            var proxSocket = socket as Socket;
            byte[] data = new byte[1024 * 1024];
            while (true)
            {
                int len = 0;
                try
                {
                    len = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
                }
                catch (Exception )
                {
                    //异常退出
                    AppendTextTolog(string.Format("客户端：{0}非常退出", proxSocket.RemoteEndPoint.ToString()));
                    ClienProSocketlist.Remove(proxSocket);
                    StopConnetct(proxSocket);
                    return;//让方法结束,终结当前客户端数据的异步线程
                }
                if (len <= 0)
                {
                    //客户端正常退出
                    AppendTextTolog(string.Format("客户端：{0}正常退出", proxSocket.RemoteEndPoint.ToString()));

                    ClienProSocketlist.Remove(proxSocket);

                    StopConnetct(proxSocket);
                    return;//让方法结束,终结当前客户端数据的异步线程
                }
                //把接收到的数据放到文本框上去
                string str = Encoding.Default.GetString(data, 0, len);
                //AppendTextTolog(str);
                

                string sss = proxSocket.RemoteEndPoint.ToString();
                var a = sss.Substring(0, sss.LastIndexOf(":"));
                var DML = string.Format("select UserName from Users where ThisIP='{0}'", a);
                SqlDataReader reader = DBHelps.Select(DML);
                if (reader.Read())
                {
                    AppendTextTolog(string.Format("{0}  ：{1}\n\r\n\r", reader["UserName"].ToString(), str));
                }
                reader.Close();
                DBHelps.reader = null;
                

                //AppendTextTolog(string.Format("接收到客户端：{0}的信息是：{1}\n\r\n\r", proxSocket.RemoteEndPoint.ToString(), str));

            }
        }

        private void StopConnetct(Socket proxSocket)
        {
            try
            {
                if (proxSocket.Connected)
                {
                    proxSocket.Shutdown(SocketShutdown.Both);
                    proxSocket.Close(100);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //往日志的文本框上追加数据
        public void AppendTextTolog(string tex)
        {
            //Action<string> sdel = a =>{ };

            //sdel = new Action<string>(a => { });

            ////sdel+=
            //sdel("sss");
            //sdel.Invoke("sss");
            //sdel.BeginInvoke("sss", null, null);


            if (texlog.InvokeRequired)
            {
                texlog.BeginInvoke(new Action<string>(s =>
                {
                    this.texlog.Text = string.Format("{0}\r\n{1}", s, texlog.Text);
                }), tex);
                //同步方法。
                //texlog.Invoke(new Action<string>(s =>
                //{
                //    this.texlog.Text = string.Format("{0}\r\n{1}",s,texlog.Text);
                //}), tex);
            }
            else
            {
                this.texlog.Text = string.Format("{0}\r\n{1}", tex, texlog.Text);
            }
            //this.texlog.Text = string.Format("{0}\r\n{1}", tex, texlog.Text);
        }

        private void butstart_Click(object sender, EventArgs e)
        {
            //1创建soclet
            Socket socket = new Socket
                (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //2绑定端口IP
            try
            {
                socket.Bind(new IPEndPoint(IPAddress.Parse(texIP.Text), int.Parse(textport.Text)));

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            //3开启倾听
            socket.Listen(10);//链接:同时来了10链接请求,只能处理一个链接,队列里面放10个等待链接的客户端,其他的返回错误消息。

            //4开始接受客户端的链接
            ThreadPool.QueueUserWorkItem(new WaitCallback(this.AccoptClientConnect), socket);

        }

        private void MasterForm_Load(object sender, EventArgs e)
        {
            texIP.Text = ThisMyInfo.GetLocalIp();
            if (ThisMyInfo.ThisIP == null)
            {
                butstart_Click(sender, e);
            }
            
            

            labIP.Visible = false;
            texIP.Visible = false;
            laport.Visible = false;
            textport.Visible = false;
            butstart.Visible = false;
            texMsg.Visible = false;
            butsendMsg.Visible = false;
        }

        private void texMsg_TextChanged(object sender, EventArgs e)
        {

        }

        private void texlog_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
